/**
 
 include this file to for your custom draws
 
 */

#pragma once

#include "zen_app.h"
#include "zen_matrix.h"
#include "zen_color.h"
#include "zen_vap_object.h"

namespace Zen { namespace Vap {
//	enum class eBlend {
//		Inherit,
//		Normal,
//		Add,
//		None,
//	};

	struct RenderBuffer
	{
		virtual ~RenderBuffer() = 0;
	};
}}

#if ZEN_APP_GLES

#include "zen_gles2.h"

namespace Zen { namespace Vap {
	using eFace = GL::eFace;
}}

#elif ZEN_APP_METAL

#include "zen_metal.h"
#include "zen_metal_prepare.h"

namespace Zen { namespace Vap {
	using namespace Metal;

	struct DrawBufferTexture
//	: DrawBuffer
	{
		VBuffer<MTVBufIN_T> v;
		UBuffer<MTUBufIN_MC> u;
		
		/// 4 vertexes for sprite label &... (with a rect view).
		void setVBufferRect4(float x0, float y0, float x1, float y1);
	};

	struct DrawBufferPoints
//	: DrawBuffer
	{
		VBuffer<MTVBufIN_P> v;
		UBuffer<MTUBufIN_MCS> u;
	};

	struct DrawBufferColors
//	: DrawBuffer
	{
		VBuffer<MTVBufIN_C> v;
		UBuffer<MTUBufIN_MC> u;
	};

	/// 3D

	struct DrawBufferTexture3D
//	: DrawBuffer
	{
		VBuffer<MTVBufIN_T3D> v;
		UBuffer<MTUBufIN_MC> u;
	};

	struct DrawBufferPoints3D
//	: DrawBuffer
	{
		VBuffer<MTVBufIN_P3D> v;
		UBuffer<MTUBufIN_MCS> u;
	};

	struct DrawBufferColors3D
//	: DrawBuffer
	{
		VBuffer<MTVBufIN_C3D> v;
		UBuffer<MTUBufIN_MC> u;
	};

	/// buffer 3D indexed
	struct UVIBufferTexture3D
	: DrawBufferTexture3D
	{
		IndexBuffer<uint32_t> i;
	};

	struct UVIBufferPoints3D
	: DrawBufferPoints3D
	{
		IndexBuffer<uint32_t> i;
	};

	struct UVIBufferColors3D
	: DrawBufferColors3D
	{
		IndexBuffer<uint32_t> i;
	};

	struct EntityBuffer
//	: DrawBuffer
	{
		VBuffer<MTVBufIN_T3D> v;
		UBuffer<MTUBufIN_MC> u;
		VBuffer<MTVBufIN_C3D> vc;
		IndexBuffer<uint32_t> i;

	};
}}

#endif


namespace Zen { namespace Vap {

	struct Helper
	{
	public:
		static Helper * Get() {
			static Helper helper;
			return &helper;
		}

	public: // step
		void initRender();

		void beginRender();

		void endRender();

	public: // kit
		void setClearColor(Color4f const & color);

		void setBlend(eBlend blend);

		void setFace(eFace face);
	};

	/// helper class for Helper
	struct RenderGuard
	{
		RenderGuard()
		{
			Helper::Get()->beginRender();
		}

		~RenderGuard()
		{
			Helper::Get()->endRender();
		}
	};
}}
